using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;

public class BuildTool : Editor
{
    [MenuItem("Tools/Build WindowsBundle")]
    public static void BundleBuildWindows()
    {
        Build(BuildTarget.StandaloneWindows);
    }

    /// <summary>
    /// 构建Bundle资源
    /// </summary>
    /// <param name="_buildTarget"></param>
    private static void Build(BuildTarget _buildTarget)
    {
        //AssetBundleBuild  -- 变量类型：用于映射bundle包资源
        List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>();

        //文件信息列表
        List<string> bundleInfos = new List<string>();

        //搜索需要打包的文件，参数列表：搜索路径，搜索的匹配字符串, 搜索选项（策略）
        string[] files = Directory.GetFiles(PathUtil.BuildResourcesPath, "*", SearchOption.AllDirectories);

        //此搜索方法会同时搜索到meta文件，但是打包时不需要meta文件，因此需要排除meta文件,在处理过程中直接使用continue跳过即可
        for (int i = 0; i < files.Length; i++)
        {
            if (files[i].EndsWith(".meta"))
                continue;

            AssetBundleBuild assetBundle = new AssetBundleBuild();

            string fileName = PathUtil.GetStandardPath(files[i]);

            string assetName = PathUtil.GetUnityPath(fileName);

            assetBundle.assetNames = new string[] { assetName };        //unity的相对目录

            //获取bundle包名字，即/BuildResources里的目录名称
            //将fileName这一目录之前的部分替换为空即可实现
            string bundleName = fileName.Replace(PathUtil.BuildResourcesPath, "").ToLower();
            assetBundle.assetBundleName = bundleName + AppConst.BundleExtension;

            //将构建完成的bundle包加入列表
            assetBundleBuilds.Add(assetBundle);

            //添加文件和依赖信息
            List<string> dependenceInfo = GetDependence(assetName);
            string bundleInfo = assetName + "|" + bundleName + AppConst.BundleExtension;

            if (dependenceInfo.Count > 0)
            {
                bundleInfo = bundleInfo + "|" + string.Join("|", dependenceInfo);
            }

            bundleInfos.Add(bundleInfo);
        }

        //检查输出路径是否存在，若存在则递归删除该路径，随后新创建该输出路径，可保证路径一定存在
        if (Directory.Exists(PathUtil.BuildOutPath))
            Directory.Delete(PathUtil.BuildOutPath, true);
        Directory.CreateDirectory(PathUtil.BuildOutPath); 

        //参数列表：输出路径，build列表(需要打成AB包的文件)，压缩格式,目标平台
        //
        BuildPipeline.BuildAssetBundles(PathUtil.BuildOutPath, assetBundleBuilds.ToArray(), BuildAssetBundleOptions.None, _buildTarget);

        //在文件中写入依赖文件等相关文件信息
        File.WriteAllLines(PathUtil.BuildOutPath + "/" + AppConst.FileListName, bundleInfos);

        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 获取依赖文件
    /// </summary>
    /// <param name="_currentFile"></param>
    /// <returns></returns>
    public static List<string>  GetDependence(string _currentFile)
    {
        List<string> dependence = new List<string>();
        string[] files = AssetDatabase.GetDependencies(_currentFile, true);
        //排除脚本文件以及文件自身
        dependence = files.Where(file => (!file.EndsWith(".cs") && !file.Equals(_currentFile))).ToList();
        return dependence;
    }
}
